From da97fcd329f54b37d4459457eb1fb7a45a59788b Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Sat, 24 Feb 2007 14:10:27 +0000 Subject: [PATCH] Support new xm command: xm trigger [] Signed-off-by: Masaki Kanno Signed-off-by: Akio Takebe Signed-off-by: Zhang Xin --- .../arch/ia64/xen/xcom_privcmd.c | 1 + tools/libxc/xc_domain.c | 15 +++++++ tools/libxc/xenctrl.h | 14 +++++++ tools/python/xen/lowlevel/xc/xc.c | 29 ++++++++++++++ tools/python/xen/xend/XendConstants.py | 10 +++++ tools/python/xen/xend/XendDomain.py | 28 +++++++++++++ tools/python/xen/xm/main.py | 16 ++++++++ xen/arch/ia64/vmx/vlsapic.c | 20 ++++++++++ xen/arch/ia64/vmx/vmx_process.c | 8 ++++ xen/arch/ia64/xen/dom0_ops.c | 40 +++++++++++++++++++ xen/include/asm-ia64/vmx.h | 2 + xen/include/asm-ia64/vmx_vpd.h | 1 + xen/include/public/domctl.h | 30 +++++++++++--- 13 files changed, 209 insertions(+), 5 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c index 0f5fccdac7..e1e312d204 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c @@ -303,6 +303,7 @@ xencomm_privcmd_domctl(privcmd_hypercall_t *hypercall) case XEN_DOMCTL_hypercall_init: case XEN_DOMCTL_arch_setup: case XEN_DOMCTL_settimeoffset: + case XEN_DOMCTL_sendtrigger: break; default: printk("%s: unknown domctl cmd %d\n", __func__, kern_op.cmd); diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 6e3b0d9e82..1b6962d54d 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -642,6 +642,21 @@ int xc_domain_iomem_permission(int xc_handle, return do_domctl(xc_handle, &domctl); } +int xc_domain_send_trigger(int xc_handle, + uint32_t domid, + uint32_t trigger, + uint32_t vcpu) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_sendtrigger; + domctl.domain = domid; + domctl.u.sendtrigger.trigger = trigger; + domctl.u.sendtrigger.vcpu = vcpu; + + return do_domctl(xc_handle, &domctl); +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 14704e2e92..3f60fdff13 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -414,6 +414,20 @@ int xc_sched_credit_domain_get(int xc_handle, uint32_t domid, struct xen_domctl_sched_credit *sdom); +/** + * This function sends a trigger to a domain. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain id to send trigger + * @parm trigger the trigger type + * @parm vcpu the vcpu number to send trigger + * return 0 on success, -1 on failure + */ +int xc_domain_send_trigger(int xc_handle, + uint32_t domid, + uint32_t trigger, + uint32_t vcpu); + /* * EVENT CHANNEL FUNCTIONS */ diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 792f57f7d4..9b11b3c5f4 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -936,6 +936,26 @@ static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args) return zero; } +static PyObject *pyxc_domain_send_trigger(XcObject *self, + PyObject *args, + PyObject *kwds) +{ + uint32_t dom; + int trigger, vcpu = 0; + + static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list, + &dom, &trigger, &vcpu) ) + return NULL; + + if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +} + static PyObject *dom_op(XcObject *self, PyObject *args, int (*fn)(int, uint32_t)) { @@ -1339,6 +1359,15 @@ static PyMethodDef pyxc_methods[] = { " dom [int]: Domain whose time offset is being set.\n" "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_send_trigger", + (PyCFunction)pyxc_domain_send_trigger, + METH_VARARGS | METH_KEYWORDS, "\n" + "Send trigger to a domain.\n" + " dom [int]: Identifier of domain to be sent trigger.\n" + " trigger [int]: Trigger type number.\n" + " vcpu [int]: VCPU to be sent trigger.\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + #ifdef __powerpc__ { "arch_alloc_real_mode_area", (PyCFunction)pyxc_alloc_real_mode_area, diff --git a/tools/python/xen/xend/XendConstants.py b/tools/python/xen/xend/XendConstants.py index e42216d06b..e6bc787340 100644 --- a/tools/python/xen/xend/XendConstants.py +++ b/tools/python/xen/xend/XendConstants.py @@ -82,6 +82,16 @@ MINIMUM_RESTART_TIME = 20 RESTART_IN_PROGRESS = 'xend/restart_in_progress' LAST_SHUTDOWN_REASON = 'xend/last_shutdown_reason' +TRIGGER_NMI = 0 +TRIGGER_RESET = 1 +TRIGGER_INIT = 2 + +TRIGGER_TYPE = { + "nmi" : TRIGGER_NMI, + "reset" : TRIGGER_RESET, + "init" : TRIGGER_INIT +} + # # Device migration stages (eg. XendDomainInfo, XendCheckpoint, server.tpmif) # diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 0c8cddde48..fbb66e1461 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -43,6 +43,7 @@ from xen.xend.XendConstants import XS_VMROOT from xen.xend.XendConstants import DOM_STATE_HALTED, DOM_STATE_PAUSED from xen.xend.XendConstants import DOM_STATE_RUNNING, DOM_STATE_SUSPENDED from xen.xend.XendConstants import DOM_STATE_SHUTDOWN, DOM_STATE_UNKNOWN +from xen.xend.XendConstants import TRIGGER_TYPE from xen.xend.XendDevices import XendDevices from xen.xend.xenstore.xstransact import xstransact @@ -1433,6 +1434,33 @@ class XendDomain: except Exception, ex: raise XendError(str(ex)) + def domain_send_trigger(self, domid, trigger_name, vcpu = 0): + """Send trigger to a domain. + + @param domid: Domain ID or Name + @type domid: int or string. + @param trigger_name: trigger type name + @type trigger_name: string + @param vcpu: VCPU to send trigger (default is 0) + @type vcpu: int + @raise XendError: failed to send trigger + @raise XendInvalidDomain: Domain is not valid + @rtype: 0 + """ + dominfo = self.domain_lookup_nr(domid) + if not dominfo: + raise XendInvalidDomain(str(domid)) + if trigger_name.lower() in TRIGGER_TYPE: + trigger = TRIGGER_TYPE[trigger_name.lower()] + else: + raise XendError("Invalid trigger: %s", trigger_name) + try: + return xc.domain_send_trigger(dominfo.getDomid(), + trigger, + vcpu) + except Exception, ex: + raise XendError(str(ex)) + def instance(): """Singleton constructor. Use this instead of the class constructor. diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 7635b06c91..ea52f0244d 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -133,6 +133,8 @@ SUBCOMMAND_HELP = { 'sched-credit': ('[-d [-w[=WEIGHT]|-c[=CAP]]]', 'Get/set credit scheduler parameters.'), 'sysrq' : (' ', 'Send a sysrq to a domain.'), + 'trigger' : (' []', + 'Send a trigger to a domain.'), 'vcpu-list' : ('[]', 'List the VCPUs for a domain or all domains.'), 'vcpu-pin' : (' ', @@ -255,6 +257,7 @@ common_commands = [ "shutdown", "start", "suspend", + "trigger", "top", "unpause", "uptime", @@ -284,6 +287,7 @@ domain_commands = [ "start", "suspend", "sysrq", + "trigger", "top", "unpause", "uptime", @@ -1347,6 +1351,17 @@ def xm_sysrq(args): req = args[1] server.xend.domain.send_sysrq(dom, req) +def xm_trigger(args): + vcpu = 0 + + arg_check(args, "trigger", 2, 3) + dom = args[0] + trigger = args[1] + if len(args) == 3: + vcpu = int(args[2]) + + server.xend.domain.send_trigger(dom, trigger, vcpu) + def xm_top(args): arg_check(args, "top", 0) @@ -1668,6 +1683,7 @@ commands = { "shutdown": xm_shutdown, "start": xm_start, "sysrq": xm_sysrq, + "trigger": xm_trigger, "uptime": xm_uptime, "suspend": xm_suspend, "list": xm_list, diff --git a/xen/arch/ia64/vmx/vlsapic.c b/xen/arch/ia64/vmx/vlsapic.c index 81b1fd46d9..a6d0a64c8a 100644 --- a/xen/arch/ia64/vmx/vlsapic.c +++ b/xen/arch/ia64/vmx/vlsapic.c @@ -497,6 +497,18 @@ chk_irq_exit: return h_pending; } +/* + * Set a INIT interruption request to vcpu[0] of target domain. + * The INIT interruption is injected into each vcpu by guest firmware. + */ +void vmx_pend_pal_init(struct domain *d) +{ + VCPU *vcpu; + + vcpu = d->vcpu[0]; + vcpu->arch.arch_vmx.pal_init_pending = 1; +} + /* * Only coming from virtualization fault. */ @@ -643,6 +655,14 @@ static void vlsapic_deliver_ipi(VCPU *vcpu, uint64_t dm, uint64_t vector) } } +/* + * Deliver the INIT interruption to guest. + */ +void deliver_pal_init(VCPU *vcpu) +{ + vlsapic_deliver_ipi(vcpu, SAPIC_INIT, 0); +} + /* * TODO: Use hash table for the lookup. */ diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index be49be8653..5e40330476 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -229,6 +229,14 @@ void leave_hypervisor_tail(void) if (v->vcpu_id == 0) { unsigned long callback_irq = d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ]; + + if ( v->arch.arch_vmx.pal_init_pending ) { + /*inject INIT interruption to guest pal*/ + v->arch.arch_vmx.pal_init_pending = 0; + deliver_pal_init(v); + return; + } + /* * val[63:56] == 1: val[55:0] is a delivery PCI INTx line: * Domain = val[47:32], Bus = val[31:16], diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index 52c3745f87..b23d222e84 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -174,6 +174,46 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) put_domain(d); } break; + + case XEN_DOMCTL_sendtrigger: + { + struct domain *d; + struct vcpu *v; + + ret = -ESRCH; + d = get_domain_by_id(op->domain); + if ( d == NULL ) + break; + + ret = -EINVAL; + if ( op->u.sendtrigger.vcpu >= MAX_VIRT_CPUS ) + goto sendtrigger_out; + + ret = -ESRCH; + if ( (v = d->vcpu[op->u.sendtrigger.vcpu]) == NULL ) + goto sendtrigger_out; + + ret = 0; + switch (op->u.sendtrigger.trigger) + { + case XEN_DOMCTL_SENDTRIGGER_INIT: + { + if (VMX_DOMAIN(v)) + vmx_pend_pal_init(d); + else + ret = -ENOSYS; + } + break; + + default: + ret = -ENOSYS; + } + + sendtrigger_out: + put_domain(d); + } + break; + default: printk("arch_do_domctl: unrecognized domctl: %d!!!\n",op->cmd); ret = -ENOSYS; diff --git a/xen/include/asm-ia64/vmx.h b/xen/include/asm-ia64/vmx.h index 3487888daf..6bf682dbf0 100644 --- a/xen/include/asm-ia64/vmx.h +++ b/xen/include/asm-ia64/vmx.h @@ -54,6 +54,8 @@ extern void vmx_relinquish_guest_resources(struct domain *d); extern void vmx_relinquish_vcpu_resources(struct vcpu *v); extern void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err); extern void vmx_send_assist_req(struct vcpu *v); +extern void deliver_pal_init(struct vcpu *vcpu); +extern void vmx_pend_pal_init(struct domain *d); static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu) { diff --git a/xen/include/asm-ia64/vmx_vpd.h b/xen/include/asm-ia64/vmx_vpd.h index e8876bb154..85bd0b1b0b 100644 --- a/xen/include/asm-ia64/vmx_vpd.h +++ b/xen/include/asm-ia64/vmx_vpd.h @@ -90,6 +90,7 @@ struct arch_vmx_struct { unsigned long flags; unsigned long xen_port; unsigned char xtp; + unsigned char pal_init_pending; #ifdef VTI_DEBUG unsigned long ivt_current; struct ivt_debug ivt_debug[IVT_DEBUG_MAX]; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index f7ea2d8acc..ce7bc480a9 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -356,6 +356,7 @@ struct xen_domctl_ioport_permission { typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t); + #define XEN_DOMCTL_hypercall_init 22 struct xen_domctl_hypercall_init { uint64_aligned_t gmfn; /* GMFN to be initialised */ @@ -363,6 +364,7 @@ struct xen_domctl_hypercall_init { typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t); + #define XEN_DOMCTL_arch_setup 23 #define _XEN_DOMAINSETUP_hvm_guest 0 #define XEN_DOMAINSETUP_hvm_guest (1UL<<_XEN_DOMAINSETUP_hvm_guest) @@ -379,15 +381,17 @@ typedef struct xen_domctl_arch_setup { } xen_domctl_arch_setup_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_arch_setup_t); + #define XEN_DOMCTL_settimeoffset 24 struct xen_domctl_settimeoffset { int32_t time_offset_seconds; /* applied to domain wallclock time */ }; typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); + -#define XEN_DOMCTL_gethvmcontext 33 -#define XEN_DOMCTL_sethvmcontext 34 +#define XEN_DOMCTL_gethvmcontext 33 +#define XEN_DOMCTL_sethvmcontext 34 typedef struct xen_domctl_hvmcontext { uint32_t size; /* IN/OUT: size of buffer / bytes filled */ XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT: data, or call gethvmcontext @@ -395,20 +399,35 @@ typedef struct xen_domctl_hvmcontext { } xen_domctl_hvmcontext_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t); -#define XEN_DOMCTL_set_address_size 35 -#define XEN_DOMCTL_get_address_size 36 + +#define XEN_DOMCTL_set_address_size 35 +#define XEN_DOMCTL_get_address_size 36 typedef struct xen_domctl_address_size { uint32_t size; } xen_domctl_address_size_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_address_size_t); -#define XEN_DOMCTL_real_mode_area 26 + +#define XEN_DOMCTL_real_mode_area 26 struct xen_domctl_real_mode_area { uint32_t log; /* log2 of Real Mode Area size */ }; typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t); + +#define XEN_DOMCTL_sendtrigger 28 +#define XEN_DOMCTL_SENDTRIGGER_NMI 0 +#define XEN_DOMCTL_SENDTRIGGER_RESET 1 +#define XEN_DOMCTL_SENDTRIGGER_INIT 2 +struct xen_domctl_sendtrigger { + uint32_t trigger; /* IN */ + uint32_t vcpu; /* IN */ +}; +typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t); + + struct xen_domctl { uint32_t cmd; uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ @@ -437,6 +456,7 @@ struct xen_domctl { struct xen_domctl_real_mode_area real_mode_area; struct xen_domctl_hvmcontext hvmcontext; struct xen_domctl_address_size address_size; + struct xen_domctl_sendtrigger sendtrigger; uint8_t pad[128]; } u; }; -- 2.30.2